#include "CCardConfig.h"

int CDivinePosConfigData::AddDrop(unsigned char ucDivinePos, unsigned char ucCardType, 
            unsigned short usDropRate, unsigned short usDropCount)
{
    if ( ucDivinePos == 0 || ucDivinePos > MAX_CARD_DIVINE_POS_CONIFG || usDropRate == 0 || usDropCount == 0)
    {
        CT_ERROR(("pos = %d, rate = %d, count = %d", ucDivinePos, usDropRate, usDropCount));
        return 0;
    }

    CRateTarget stDrop;
    stDrop._iTargetID = ucCardType;
    stDrop._iMaxCount = CRateTarget::TARGET_INFINITY;
    stDrop._iRate = usDropRate;
    stDrop._iData1 = usDropCount;
    CT_TRACE(("add drop config , pos = %d", ucDivinePos));
    return _astDivinePosDropSet[ucDivinePos].Add(stDrop);
}

int CDivinePosConfigData::Drop(CRateTarget& stDrop, unsigned char ucPos, unsigned short& usDropCount)
{
    if ( ucPos == 0 || ucPos > MAX_CARD_DIVINE_POS_CONIFG )
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    int iRet = 0;
    iRet = _astDivinePosDropSet[ucPos].DropOne(stDrop);
    CHECK_RETURN(iRet);
    usDropCount = (unsigned short)stDrop._iData1;
    return 0;
}

//////////////////////////////////////////////////////////////////////////

int CDivinePosConfig::AddConfig(CDivinePosConfigData& stConfigData)
{
    if (stConfigData._ucDivinePos <= 0 || stConfigData._ucDivinePos > MAX_CARD_DIVINE_POS_CONIFG)
    {
        return ERROR_CARD_DIVINE_POS_CONFIG;
    }

    if (_astDivinePosConfig[stConfigData._ucDivinePos]._bHasConfig)
    {
        return ERROR_CARD_DIVINE_POS_CONFIG_DUPLICATE;
    }

    _astDivinePosConfig[stConfigData._ucDivinePos] = stConfigData;
    _astDivinePosConfig[stConfigData._ucDivinePos]._bHasConfig = true;

    return 0;
}

int CDivinePosConfig::GetConfig(unsigned char ucPos, CDivinePosConfigData& stConfigData)
{
    if (ucPos <= 0 || ucPos > MAX_CARD_DIVINE_POS_CONIFG)
    {
        return ERROR_CARD_DIVINE_POS_CONFIG;
    }

    if (!_astDivinePosConfig[ucPos]._bHasConfig)
    {
        return ERROR_CARD_DIVINE_POS_CONFIG;
    }

    stConfigData = _astDivinePosConfig[ucPos];
    return 0;
}

int CDivinePosConfig::AddGoldDrop(unsigned char ucCardType, unsigned short usDropRate)
{
    if (usDropRate == 0)
    {
        CT_ERROR(("rate = %d", usDropRate));
        return 0;
    }

    CRateTarget stDrop;
    stDrop._iTargetID = ucCardType;
    stDrop._iMaxCount = CRateTarget::TARGET_INFINITY;
    stDrop._iRate = usDropRate;
    stDrop._iData1 = 1;

    return _stGoldDivineDropSet.Add(stDrop);
}

int CDivinePosConfig::GoldDrop(CRateTarget& stDrop)
{
    int iRet = 0;
    iRet = _stGoldDivineDropSet.DropOne(stDrop);
    CHECK_RETURN(iRet);

    return 0;
}

//////////////////////////////////////////////////////////////////////////
int CCardLevelConfigData::GetExp(unsigned char ucCardType, unsigned int& uiExp)
{
    switch (ucCardType)
    {
    case CARD_TYPE_GREEN_CARD:
        uiExp = _uiType2Exp;
        break;
    case CARD_TYPE_BLUE_CARD:
        uiExp = _uiType3Exp;
        break;
    case CARD_TYPE_PURPLE_CARD:
        uiExp = _uiType4Exp;
        break;
    case CARD_TYPE_SOUL_CARD:
        uiExp = _uiType5Exp;
        break;
    case CARD_TYPE_GOLD_CARD:
        uiExp = _uiType6Exp;
        break;
    case CARD_TYPE_ORANGE_CARD:
        uiExp = _uiType8Exp;
        break;
    default:
        return ERROR_CARD_WRONG_TYPE;
    }

    return 0;
}

CCardLevelConfigData& CCardLevelConfigData::operator+=(const CCardLevelConfigData& stData)
{
    _uiType2Exp += stData._uiType2Exp;
    _uiType3Exp += stData._uiType3Exp;
    _uiType4Exp += stData._uiType4Exp;
    _uiType5Exp += stData._uiType5Exp;
    _uiType6Exp += stData._uiType6Exp;
    _uiType8Exp += stData._uiType8Exp;

    return *this;
}

//////////////////////////////////////////////////////////////////////////
int CCardLevelConfig::AddConfig(CCardLevelConfigData& stConfigData)
{
    if (stConfigData._usLevel <= 0 || stConfigData._usLevel > MAX_CARD_LEVEL)
    {
        return ERROR_CARD_LEVEL;
    }

    if (_astCardLevelConfig[stConfigData._usLevel]._bHasConfig)
    {
        CT_ERROR(("CCardLevelConfig AddConfig"));
        return RET_SYS_ERROR;
    }

    _astCardLevelConfig[stConfigData._usLevel] = stConfigData;
    _astCardLevelConfig[stConfigData._usLevel]._bHasConfig = true;
    
    if (stConfigData._usLevel > _stMaxLevelConfigData._usLevel)
    {
        _stMaxLevelConfigData = _astCardLevelConfig[stConfigData._usLevel];
    }

    //卡片分数配置
    if (stConfigData._usLevel > 1)
    {
        _astCardBasePoint[stConfigData._usLevel] = _astCardBasePoint[stConfigData._usLevel - 1];
        _astCardBasePoint[stConfigData._usLevel] += stConfigData;
        _astCardBasePoint[stConfigData._usLevel]._bHasConfig = true;
    }
    
    return 0;
}

int CCardLevelConfig::GetConfig(unsigned short usLevel, unsigned char ucCardType, unsigned int& uiExp)
{
    if (usLevel <= 0 || usLevel > MAX_CARD_LEVEL)
    {
        return ERROR_CARD_LEVEL;
    }

    if (!_astCardLevelConfig[usLevel]._bHasConfig)
    {
        return ERROR_CARD_LEVEL;
    }

    return _astCardLevelConfig[usLevel].GetExp(ucCardType, uiExp);
}

int CCardLevelConfig::GetPointConfig(unsigned short usLevel, unsigned char ucCardType, unsigned int& uiPoint)
{
    int iRet = 0;
    uiPoint = 0;

    if (usLevel <= 0 || usLevel > MAX_CARD_LEVEL)
    {
        return ERROR_CARD_LEVEL;
    }

    if (!_astCardLevelConfig[usLevel]._bHasConfig)
    {
        return ERROR_CARD_LEVEL;
    }

    iRet = _astCardBasePoint[usLevel].GetExp(ucCardType, uiPoint);
    CHECK_RETURN(iRet);

    uiPoint = uiPoint / 30;
    
    return 0;
}

//////////////////////////////////////////////////////////////////////////
CCardDrop::CCardDrop()
{
    _astCardDropSet.m_iUsedCount = _astCardDropSet.GetCount();
    for (int i = 0; i < _astCardDropSet.Size(); ++i)
    {
        T_CARD_DROP_SET_PER_GRAD& stCardDropSetPerGrad = _astCardDropSet[i];
        stCardDropSetPerGrad.m_iUsedCount = stCardDropSetPerGrad.GetCount();
    }

    _astGoldCardDropSet.m_iUsedCount = _astGoldCardDropSet.GetCount();
    for (int i = 0; i < _astGoldCardDropSet.Size(); ++i)
    {
        T_CARD_DROP_SET_PER_GRAD& stCardDropSetPerGrad = _astGoldCardDropSet[i];
        stCardDropSetPerGrad.m_iUsedCount = stCardDropSetPerGrad.GetCount();
    }
}

char CCardDrop::GetLevelGrad(unsigned short usLevel)
{
    if (usLevel >= 0 && usLevel <= 39)
    {
        return 1;
    }
    else if (usLevel >= 40 && usLevel <= 59)
    {
        return 2;
    }
    else if (usLevel >= 60 && usLevel <= 79)
    {
        return 3;
    }
    else if (usLevel >= 80 && usLevel <= 99)
    {
        return 4;
    }
    else if (usLevel >= 100 && usLevel <= 109)
    {
        return 5;
    }
    else if (usLevel >= 110 && usLevel <= 119)
    {
        return 6;
    }
    else if (usLevel >= 120 && usLevel <= 150)
    {
        return 7;
    }
    else 
    {
        return -1;
    }
}

int CCardDrop::GetCardIndex(unsigned char ucCardType)
{
    switch(ucCardType)
    {
    case CARD_TYPE_GREEN_CARD:
        return 0;
    case CARD_TYPE_BLUE_CARD:
        return 1;
    case CARD_TYPE_PURPLE_CARD:
        return 2;
    case CARD_TYPE_SOUL_CARD:
        return 3;
    case CARD_TYPE_GOLD_CARD:
        return 4;
    case CARD_TYPE_ORANGE_CARD:
        return 4;                       //橙色作为金色的掉落
    default:
        return -1;
    }
}

int CCardDrop::GetGoldCardIndex(unsigned char ucCardType)
{
    switch(ucCardType)
    {
    case CARD_TYPE_GREEN_CARD:
        return 0;
    case CARD_TYPE_BLUE_CARD:
        return 1;
    case CARD_TYPE_PURPLE_CARD:
        return 2;
    case CARD_TYPE_SOUL_CARD:
        return 3;
    case CARD_TYPE_GOLD_CARD:
        return 4;
    case CARD_TYPE_ORANGE_CARD:
        return 5;                      
    default:
        return -1;
    }
}

int CCardDrop::AddDropData(char cLevelGrad, unsigned char ucCardType,
                unsigned short usCardConfigID, int iDropRate)
{
    int iRet = 0;
    if (cLevelGrad <= 0 || cLevelGrad >= _astCardDropSet.GetCount())
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    int iIndex = GetCardIndex(ucCardType);
    if (iIndex < 0)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    CRateTarget stDrop;
    stDrop._iTargetID = usCardConfigID;
    stDrop._iMaxCount = CRateTarget::TARGET_INFINITY;
    stDrop._iRate = iDropRate;
    iRet = _astCardDropSet[cLevelGrad][iIndex].Add(stDrop);
    CHECK_RETURN(iRet);

    //金币占卜配置
    iIndex = GetGoldCardIndex(ucCardType);
    if (iIndex < 0)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    iRet = _astGoldCardDropSet[cLevelGrad][iIndex].Add(stDrop);
    CHECK_RETURN(iRet);

    return 0;
}

int CCardDrop::Drop(unsigned short usLevel, unsigned char ucCardType, unsigned short& usCardConfigID)
{
    char cGrad = GetLevelGrad(usLevel);
    if (cGrad <= 0 || cGrad > _astCardDropSet.Size())
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    int iIndex = GetCardIndex(ucCardType);
    if (iIndex < 0 || iIndex >= _astCardDropSet[cGrad].Size())
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    CRateTarget stDrop;
    int iRet = _astCardDropSet[cGrad][iIndex].DropOne(stDrop);
    if (iRet != RET_OK)
    {
        return iRet;
    }

    usCardConfigID = (unsigned short)stDrop._iTargetID;
    return 0;
}

int CCardDrop::GoldDrop(unsigned short usLevel, unsigned char ucCardType, unsigned short& usCardConfigID)
{
    char cGrad = GetLevelGrad(usLevel);
    if (cGrad <= 0 || cGrad > _astGoldCardDropSet.Size())
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    int iIndex = GetGoldCardIndex(ucCardType);
    if (iIndex < 0 || iIndex >= _astGoldCardDropSet[cGrad].Size())
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    CRateTarget stDrop;
    int iRet = _astGoldCardDropSet[cGrad][iIndex].DropOne(stDrop);
    if (iRet != RET_OK)
    {
        return iRet;
    }

    usCardConfigID = (unsigned short)stDrop._iTargetID;
    return 0;
}

//////////////////////////////////////////////////////////////////////////
int CCardConfig::AddConfig(CCardConfigData& stConfigData)
{
    if (stConfigData._usCardConfigID <= 0 || stConfigData._usCardConfigID > MAX_CARD_CONFIG_COUNT)
    {
        return ERROR_CARD_ID;
    }

    if (_astCardConfig[stConfigData._usCardConfigID]._bHasConfig)
    {
        CT_ERROR(("CCardConfig AddConfig"));
        return ERROR_CARD_ID;
    }

    _astCardConfig[stConfigData._usCardConfigID] = stConfigData;
    _astCardConfig[stConfigData._usCardConfigID]._bHasConfig = true;

    for (int i = 0; i < stConfigData._astDropRate.Size(); ++i)
    {
        _stCardDrop.AddDropData(i + 1, stConfigData._ucCardType, stConfigData._usCardConfigID, 
            stConfigData._astDropRate[i]);
    }

    return 0;
}

int CCardConfig::GetConfig(unsigned short usCardConfigID, CCardConfigData& stConfigData)
{
    if (usCardConfigID <= 0 || usCardConfigID > MAX_CARD_CONFIG_COUNT)
    {
        return ERROR_CARD_ID;
    }

    if (!_astCardConfig[usCardConfigID]._bHasConfig)
    {
        CT_ERROR(("CCardConfig GetConfig"));
        return ERROR_CARD_ID;
    }

    stConfigData = _astCardConfig[usCardConfigID];
    return 0;
}


int CCardConfig::Drop(unsigned short usLevel, unsigned char ucCardType, unsigned short& usCardConfigID)
{
    return _stCardDrop.Drop(usLevel, ucCardType, usCardConfigID);
}

int CCardConfig::GoldDrop(unsigned short usLevel, unsigned char ucCardType, unsigned short& usCardConfigID)
{
    return _stCardDrop.GoldDrop(usLevel, ucCardType, usCardConfigID);
}

//////////////////////////////////////////////////////////////////////////

int CVortexConfig::AddConfig(CVortexConfigData& stConfigData)
{
    if (stConfigData._usLevel > MAX_VORTEX_CONFIG_COUNT)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    if (_astVortexConfigDatas[stConfigData._usLevel]._bHasConfig)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    _astVortexConfigDatas[stConfigData._usLevel] = stConfigData;
    _astVortexConfigDatas[stConfigData._usLevel]._bHasConfig = true;

    if (stConfigData._usLevel == 0)
    {
        return 0;
    }

    if (!_astVortexConfigDatas[stConfigData._usLevel - 1]._bHasConfig)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    _astVortexConfigDatas[stConfigData._usLevel]._uiNeedFateForceCount 
            += _astVortexConfigDatas[stConfigData._usLevel - 1]._uiNeedFateForceCount;

    if (stConfigData._usLevel == 1)
    {
        _astVortexConfigDatas[stConfigData._usLevel]._uiExtractToZeroNeedSilver
            = _astVortexConfigDatas[stConfigData._usLevel]._uiExtractNeedSilver;
    }
    else
    {
        _astVortexConfigDatas[stConfigData._usLevel]._uiExtractToZeroNeedSilver
            = (_astVortexConfigDatas[stConfigData._usLevel]._uiExtractNeedSilver
                    + _astVortexConfigDatas[stConfigData._usLevel - 1]._uiExtractToZeroNeedSilver);
    }

    usMaxLevel = CT_MAX(usMaxLevel, stConfigData._usLevel);
    return 0;
}

int CVortexConfig::GetConfig(unsigned short usLevel, CVortexConfigData& stConfigData)
{
    if (usLevel > MAX_VORTEX_CONFIG_COUNT)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR;
    }

    if (!_astVortexConfigDatas[usLevel]._bHasConfig)
    {
        CT_ERROR((""));
        return RET_SYS_ERROR; 
    }

    stConfigData = _astVortexConfigDatas[usLevel];
    return 0;
}
